package JUEGO;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.io.*;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Random;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import INTERFAZ.Dibujador;
import MUNDO.GestorMapas;
import OBJETOS.ArmaAtaque;
import OBJETOS.ArmaDef;
import PERSONAJES.Personaje;
public class Juego implements Serializable{
	
	
	private static Hilo HiloEnemigo;
	public static Hilo getHiloEnemigo() {
		return HiloEnemigo;
	}

	public static Dibujador D;
	private static int dinero=2000;
	private static int batallonactual=1;
	private static int enemigoactual=1;
	private static ArrayList<Integer> batallonesX=new ArrayList<Integer>();
	public static ArrayList<Integer> getBatallonesX() {
		return batallonesX;
	}
	public static ArrayList<Integer> getBatallonesY() {
		return batallonesY;
	}

	private static ArrayList<Integer> batallonesY=new ArrayList<Integer>();
	public static ArrayList<Integer> getEnemigosX() {
		return EnemigosX;
	}
	public static ArrayList<Integer> getEnemigosY() {
		return EnemigosY;
	}

	public static void setD(Dibujador d) {
		D = d;
	}
	public static void setBatallonesX(ArrayList<Integer> batallonesX) {
		Juego.batallonesX = batallonesX;
	}
	public static void setBatallonesY(ArrayList<Integer> batallonesY) {
		Juego.batallonesY = batallonesY;
	}
	public static void setEnemigosX(ArrayList<Integer> enemigosX) {
		EnemigosX = enemigosX;
	}
	public static void setEnemigosY(ArrayList<Integer> enemigosY) {
		EnemigosY = enemigosY;
	}

	private static ArrayList<Integer> EnemigosX=new ArrayList<Integer>();
	private static ArrayList<Integer> EnemigosY=new ArrayList<Integer>();
	private static int turno=1;//1 es muestro turno
								//2 turno de la computadora
	
	
	public static int getBatallonactual() {return batallonactual;}
	public static int getEnemigoactual() {return enemigoactual;}
	public static void setBatallonactual(int BatallonActual) { batallonactual=BatallonActual;}
	public static void setEnemigoactual(int EnemigoActual) { enemigoactual=EnemigoActual;}	
	public static void setBatallonesXY(int m,int x,int y) {
		if (m>=batallonesX.size())batallonesX.add(x);else Juego.batallonesX.set(m,x);
		if (m>=batallonesY.size())batallonesY.add(y);else Juego.batallonesY.set(m,y);
	}
	public static void setEnemigosXY(int m,int x,int y) {
		if (m>=EnemigosX.size())EnemigosX.add(x);else Juego.EnemigosX.set(m,x);
		if (m>=EnemigosY.size())EnemigosY.add(y);else Juego.EnemigosY.set(m,y);
	}
	public static int getCoorXBatallon(int i){return batallonesX.get(i-1);}
	public static int getTurno(){return turno;}
	public static int getCoorYBatallon(int i){return batallonesY.get(i-1);}
	public static int getCoorXEnemigo(int i){return EnemigosX.get(i-1);}
	public static int getCoorYEnemigo(int i){return EnemigosY.get(i-1);}
		
	//private static Batallon [] batallonenemigoX = new Batallon [12];
	//private static int numbatenemigo=0;
	
	public static int getNumbatallones() {return batallonesX.size();}
	public static int getNumEnemigos() {return EnemigosX.size();}
	//public static void setNumbatallones(int numbatallones) {Juego.numbatallones = numbatallones;}
	public static  int getDinero() {return dinero;}

	public static void setDinero(int dinero) {
		Juego.dinero = dinero;}

	public static void creaTurno(){
		HiloEnemigo = new Hilo("turno");
		HiloEnemigo.start();
		synchronized(HiloEnemigo){
			HiloEnemigo.notify();
			
		}
		
	}
	public static synchronized void CambiarBatallon(int x, int y, int ind_mapa,GestorMapas episodios){
		
		//System.out.println(batallonesX.size());
		for (int j = 0; j < batallonesX.size(); j++){
			//System.out.println(batallonesX.get(j) +"  " + batallonesY.get(j));
			if (batallonesX.get(j) == x && batallonesY.get(j) == y){
				batallonactual = j+1;
				break;
			}
			
			
		}
		
		episodios.obtenerMapa(ind_mapa).setCoordX(batallonesX.get(batallonactual-1)); 
		episodios.obtenerMapa(ind_mapa).setCoordY(batallonesY.get(batallonactual-1));
		
    
		D.set_dibujar(episodios.obtenerMapa(ind_mapa).getCoordX(), 
			episodios.obtenerMapa(ind_mapa).getCoordY(),
			episodios.obtenerMapa(ind_mapa));
    
		D.update(D.getGraphics());
		
	}
	
	public static synchronized void CurarUnidades(int ind_mapa,GestorMapas episodios){
		int batallon=batallonactual-1;
		episodios.obtenerMapa(ind_mapa)
		.getTerreno(batallonesX.get(batallon) , batallonesY.get(batallon))
		.getBatallon().curacion(D);
		
		//if (D.getCurada() == 1){
			//Juego.turno=2;
			//Turnoenemigo(ind_mapa,episodios);
		//}
		
		
		D.set_dibujar(episodios.obtenerMapa(ind_mapa).getCoordX(), 
			episodios.obtenerMapa(ind_mapa).getCoordY(),
			episodios.obtenerMapa(ind_mapa));
    
		D.update(D.getGraphics());
	}
	
	
	public static synchronized void MoverBatallon(char pos,int ind_mapa,GestorMapas episodios) {		
        	if (episodios.obtenerMapa(ind_mapa).realizarMov(pos,episodios.obtenerMapa(ind_mapa).getCoordX(), 
                											episodios.obtenerMapa(ind_mapa).getCoordY())==1){
            		//Juego.turno=2;
                //Turnoenemigo(ind_mapa,episodios);
        	}
                D.set_dibujar(episodios.obtenerMapa(ind_mapa).getCoordX(), 
    					episodios.obtenerMapa(ind_mapa).getCoordY(),
    					episodios.obtenerMapa(ind_mapa));
                
                D.update(D.getGraphics());	
	}
	public static synchronized void Turnoenemigo(int ind_mapa,GestorMapas episodios) {
		
		Juego.turno=2;
		char ord='a';
		Random random =new Random();// el enemigo solo puede atacar y mover

    	while(true){	
    		switch (random.nextInt(4)){//para seleccionar la direccion
    		case 0:ord='w';D.setEnemigo(2);break;
    		case 1:ord='a';D.setEnemigo(4);break;
    		case 2:ord='s';D.setEnemigo(1);break;
    		case 3:ord='d';D.setEnemigo(3);break;
    		}
			if(random.nextInt(2)==0){ //el enemigo se mueve
	    		if(episodios.obtenerMapa(ind_mapa).realizarMov(ord,
						episodios.obtenerMapa(ind_mapa).getCoordEnemigoX(), 
						episodios.obtenerMapa(ind_mapa).getCoordEnemigoY())==1)break;
	    	}
	    	else{ // el enemigo ataca
	    		if(episodios.obtenerMapa(ind_mapa).realizarAtaque(D,ord,
						episodios.obtenerMapa(ind_mapa).getCoordEnemigoX(), 
						episodios.obtenerMapa(ind_mapa).getCoordEnemigoY())==1)break;	
	    	}
		}
    	episodios.obtenerMapa(ind_mapa).setCoordEnemigoX(EnemigosX.get(enemigoactual-1)); 
		episodios.obtenerMapa(ind_mapa).setCoordEnemigoY(EnemigosY.get(enemigoactual-1));
    	
    	//ahora le toca jugar al usuario
    	
		  Juego.turno=1;
		D.set_dibujar(episodios.obtenerMapa(ind_mapa).getCoordX(), 
				episodios.obtenerMapa(ind_mapa).getCoordY(),
				episodios.obtenerMapa(ind_mapa));
        
        D.update(D.getGraphics());
    	
	}

	public static synchronized void DatoBatallon(int batallon,int ind_mapa, GestorMapas episodios){
		int limite = episodios.obtenerMapa(ind_mapa).getTerreno(batallonesX.get(batallon) , batallonesY.get(batallon)).getBatallon().getNpersonajes();
		episodios.obtenerMapa(ind_mapa).getTerreno(batallonesX.get(batallon) , batallonesY.get(batallon)).getBatallon().ordenar_personaje();
		for (int j = 0; j < limite; j++)
			episodios.obtenerMapa(ind_mapa).getTerreno(batallonesX.get(batallon) , batallonesY.get(batallon)).getBatallon().getPersonaje(j).mostrarPersonaje();

	}
	
	
	
	
	
	public static synchronized void AtacarBatallon(char pos, int ind_mapa,GestorMapas episodios){
        		
        	episodios.obtenerMapa(ind_mapa).realizarAtaque(D, pos,
            											episodios.obtenerMapa(ind_mapa).getCoordX(), 
            											episodios.obtenerMapa(ind_mapa).getCoordY());
            
        	//Juego.turno=2;
            //Turnoenemigo(ind_mapa,episodios);
            
            D.set_dibujar(episodios.obtenerMapa(ind_mapa).getCoordX(), 
				episodios.obtenerMapa(ind_mapa).getCoordY(),
				episodios.obtenerMapa(ind_mapa));
        
            D.update(D.getGraphics());
            
          
            
        
		
	}
	
	public static synchronized void AdquirirArmas(char pos, int ind_mapa,GestorMapas episodios){
		
        episodios.obtenerMapa(ind_mapa).realizarCompra(D,pos,
            											episodios.obtenerMapa(ind_mapa).getCoordX(), 
            											episodios.obtenerMapa(ind_mapa).getCoordY(), batallonactual);
            
        //Juego.turno=2;
        //Turnoenemigo(ind_mapa,episodios);
    
        D.set_dibujar(episodios.obtenerMapa(ind_mapa).getCoordX(), 
			episodios.obtenerMapa(ind_mapa).getCoordY(),
			episodios.obtenerMapa(ind_mapa));
    
        D.update(D.getGraphics());
        
	}
	
	
	public static synchronized void ReclutarAliados(char pos, int ind_mapa, GestorMapas episodios) {
    		episodios.obtenerMapa(ind_mapa).realizarConvencer(D,pos,
							episodios.obtenerMapa(ind_mapa).getCoordX(), 
							episodios.obtenerMapa(ind_mapa).getCoordY(), batallonactual-1);
    		
    		//Juego.turno=2;
           // Turnoenemigo(ind_mapa,episodios);
            
            D.set_dibujar(episodios.obtenerMapa(ind_mapa).getCoordX(), 
				episodios.obtenerMapa(ind_mapa).getCoordY(),
				episodios.obtenerMapa(ind_mapa));
        
            D.update(D.getGraphics());
	}
	
	public static synchronized void MuerteBatallon(int x, int y,int bando){
		if (bando==1){
			for (int j = 0; j < batallonesX.size(); j++){
				if (batallonesX.get(j) == x && batallonesY.get(j) == y){
					if (j == 0&&bando==1) GameOver();
					batallonesX.remove(j);
					batallonesY.remove(j);
					break;
				}
			}
		}
		else if (bando==2){
			for (int j = 0; j < EnemigosX.size(); j++){
				if (EnemigosX.get(j) == x && EnemigosY.get(j) == y){
					EnemigosX.remove(j);
					EnemigosY.remove(j);
					break;
				}
			}
			
			
		}
	}
	public static synchronized void Win(){
		


		D.flag = 2;
		
		D.update(D.getGraphics());
		int i=0,j=0;
		while(i<1000000000){
			while(j<1000000000)j++;
			i++;
	    }
//		JOptionPane.showMessageDialog(D,
//				"Jose Angulo ha muerto...\n"+"Usted ha perdido. Juego Terminado!",
//			    "JUEGO TERMINADO",
//			    JOptionPane.WARNING_MESSAGE);

		System.exit(0);
	}
	public static synchronized void GameOver(){
		


		D.flag = 1;
		
		D.update(D.getGraphics());
		int i=0,j=0;
		while(i<1000000000){
			while(j<1000000000)j++;
			i++;
	    }
//		JOptionPane.showMessageDialog(D,
//				"Jose Angulo ha muerto...\n"+"Usted ha perdido. Juego Terminado!",
//			    "JUEGO TERMINADO",
//			    JOptionPane.WARNING_MESSAGE);

		System.exit(0);
	}
	

	public static synchronized void ParadaNeutral(char unidad, int ipos, int jpos){
		Juego.D.AccionNeutral(unidad, ipos, jpos);
	}
	
	public static synchronized void ParadaEnemigo(int boton, int ipos, int jpos){
		Juego.D.AccionEnemigo(boton, ipos, jpos);
	}
	
	public static synchronized void SalidaJuego(){
		Object[] options = {"Si","No"};
		int n = JOptionPane.showOptionDialog(D,
				"Desea salir del juego?",
						"Salir del Juego",
						JOptionPane.YES_NO_OPTION,
						JOptionPane.QUESTION_MESSAGE,
						null,
						options,
						options[1]);
		
		if (n == JOptionPane.YES_OPTION){System.exit(0);}
	}
	
	
	
	
	
	
	public static void cargarArchivo() throws IOException {
        //PARA LEER UN MAPA DESDE UN ARCHIVO DE TEXTO
        File fMapa = new File( "ArchivosConfiguracion/mapa.txt" );//se indica de que archivo se va a leer
        if ( fMapa.exists() )
        	leeMapa(fMapa);
        
        File fPers = new File( "ArchivosConfiguracion/personajes.txt" );//se indica de que archivo se va a leer
        if ( fPers.exists() )
        	leePers(fPers);

        File fArmasA = new File( "ArchivosConfiguracion/armasAtaque.txt" );//se indica de que archivo se va a leer
        if ( fArmasA.exists() )
        	leerArmasA(fArmasA);        
        File fArmasD = new File( "ArchivosConfiguracion/armasDefensa.txt" );//se indica de que archivo se va a leer
        if ( fArmasD.exists() )
        	leerArmasD(fArmasD); 
	}
	
	public static int visionX;//Lo usamos en la clase Main para leer la vision del personaje
	public static int visionY;//Lo usamos en la clase Main para leer la vision del personaje	
	public static int filasMapa;
	public static int columMapa;
	public static String []mapa;//Va a contener todo el mapa leido del arch de texto
	
	public static void leeMapa(File f) throws IOException{
        FileReader freader=new FileReader(f);
        BufferedReader entrada = new BufferedReader(freader);
        int i=-1;
        String linea=entrada.readLine();
        while(linea!=null ){
        	String [] tokens = linea.split(" ");
            i++;
			if(i==0) {//Leemos la vision del Personaje que es la primera linea del arch de texto
				visionX=Integer.parseInt(tokens[0]);
				visionY=Integer.parseInt(tokens[1]);
			}
			//Leemos el mapa del juego
			else if(i==1){// es la 2da linea del arch
				filasMapa=Integer.parseInt(tokens[0]);
				columMapa=Integer.parseInt(tokens[1]);
				mapa=new String[filasMapa];
			}
			else if(1<i && i<= (filasMapa+1) ){//Leemos la lineas del mapa
				mapa[i-2]=linea;
                //System.out.println(i-1+":"+mapa[i-2]);
                if (i==1+filasMapa) calularValoresIniciales();//Se calcula la posicion inicial del batallon principal
            }
            linea=entrada.readLine();
        }
    }
	public static int xIniciaBatallon;
	public static int yIniciaBatallon;
	public static int xUltimoBatallonEnermigo;
	public static int yUltimoBatallonEnermigo;
	private static void calularValoresIniciales() {
		//Vamos a calular la posicion del Batallon principal
		int i=0;int j=0;
		for(i=0;i<20;i++)
			for(j=0;j<20;j++) 
				if (mapa[i].charAt(j)=='A') {
					xIniciaBatallon=i;
					yIniciaBatallon=j;
					break;
				}
		i=0;j=0;
		for(i=0;i<20;i++)
			for(j=0;j<20;j++) 
				if (mapa[i].charAt(j)=='e') {
					xUltimoBatallonEnermigo=i;
					yUltimoBatallonEnermigo=j;
				}
		//System.out.println(xUltimoBatallonEnermigo+" "+yUltimoBatallonEnermigo);	
	}

	public static Vector<Personaje> vPers = new Vector();
	
	public static void leePers(File f) throws IOException{
        FileReader freader=new FileReader(f);
        BufferedReader entrada = new BufferedReader(freader);
        entrada.readLine();
        String linea=entrada.readLine();
        while(linea!=null ){
        	String [] tokens = linea.split("/");
        	Personaje pers=new Personaje();
        	pers.setNombre(tokens[0]); 
        	pers.setVidaMax(Integer.parseInt(tokens[1]));
        	pers.setAtaque(Integer.parseInt(tokens[2]));
        	pers.setDefensa(Integer.parseInt(tokens[3]));
        	pers.setCuracion(Integer.parseInt(tokens[4]));
        	pers.setTipo(Integer.parseInt(tokens[5]));
        	vPers.add(pers);
            linea=entrada.readLine();
        }
    }
	
	public static Vector<ArmaAtaque> vArmaA = new Vector();
	
	public static void leerArmasA(File f) throws IOException{
        FileReader freader=new FileReader(f);
        BufferedReader entrada = new BufferedReader(freader);
        entrada.readLine();//La primera linea tiene el prototipo
        String linea=entrada.readLine();
        while(linea!=null ){
        	//    nombre/ataque/codigo/precio/descripcion
        	String [] tokens = linea.split("/");
        	ArmaAtaque armaA=new ArmaAtaque();
        	armaA.setNombre(tokens[0]);
        	armaA.setAtaque(Integer.parseInt(tokens[1]));
        	armaA.setCodigo(Integer.parseInt(tokens[2]));
        	armaA.setPrecio(Integer.parseInt(tokens[3]));
        	armaA.setDesc(tokens[4]);
        	vArmaA.add(armaA);
            linea=entrada.readLine();
        }
    }
	
	public static Vector<ArmaDef> vArmaD = new Vector();
	
	public static void leerArmasD(File f) throws IOException{
        FileReader freader=new FileReader(f);
        BufferedReader entrada = new BufferedReader(freader);
        entrada.readLine();//La primera linea tiene el prototipo
        String linea=entrada.readLine();
        while(linea!=null ){
        	//    nombre/defensa/codigo/precio/descripcion
        	String [] tokens = linea.split("/");
        	ArmaDef armaD=new ArmaDef();
        	armaD.setNombre(tokens[0]);
        	armaD.setDefensa(Integer.parseInt(tokens[1]));
        	armaD.setCodigo(Integer.parseInt(tokens[2]));
        	armaD.setPrecio(Integer.parseInt(tokens[3]));
        	armaD.setDesc(tokens[4]);
        	vArmaD.add(armaD);
            linea=entrada.readLine();
        }
    }
}